package com.xyht.sca_s.student_manage_system.modules.commonExamine.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.ApiModelUtil;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.common.util.PictureUtil;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.common.constant.FileSavePathConstant;
import com.xyht.sca_s.student_manage_system.modules.commonExamine.entity.*;
import com.xyht.sca_s.student_manage_system.modules.commonExamine.entity.req.SmsCommonExamineHistoryReq;
import com.xyht.sca_s.student_manage_system.modules.commonExamine.entity.req.SmsCommonExamineReq;
import com.xyht.sca_s.student_manage_system.modules.commonExamine.entity.resp.*;
import com.xyht.sca_s.student_manage_system.modules.commonExamine.mapper.*;
import com.xyht.sca_s.student_manage_system.modules.commonExamine.service.SmsCommonExamineService;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.AppTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.CopyTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.RangeTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.util.NewTipsUtil;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.commonExamine.constant.CommonConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.commonExamine.constant.examineStatusConstant.EXAMINE_STATUS_CANCEL;
import static com.xyht.sca_s.student_manage_system.modules.commonExamine.constant.examineStatusConstant.EXAMINE_STATUS_WAIT_ALLOW;
import static com.xyht.sca_s.student_manage_system.modules.commonExamine.constant.examineTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.examinePaymentEquipment.constant.isExportProcessConstant.EXPORT_PROCESS_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.examinePaymentEquipment.constant.paymentExamineStatusConstant.EXAMINE_STATUS_DENY;
import static com.xyht.sca_s.student_manage_system.modules.examinePaymentEquipment.constant.paymentExamineStatusConstant.EXAMINE_STATUS_PASS;
import static com.xyht.sca_s.student_manage_system.modules.student.constant.StudentInfoCommonConstant.PER_SHEET_NUM;

/**
 * <p>
 * 通用审批 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-04-24
 */
@Service
public class SmsCommonExamineServiceImpl extends ServiceImpl<SmsCommonExamineMapper, SmsCommonExamine> implements SmsCommonExamineService {
    @Resource
    private FileSavePathConstant fileSavePathConstant;
    @Autowired
    private SmsCommonExamineMapper smsCommonExamineMapper;
    @Autowired
    private SmsCommonExamineProcessMapper smsCommonExamineProcessMapper;
    @Autowired
    private SmsCommonExamineCopyMapper smsCommonExamineCopyMapper;
    @Autowired
    private SmsUserMapper smsUserMapper;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private SmsCommonExamineProcessMpjMapper smsCommonExamineProcessMpjMapper;
    @Autowired
    private SmsCommonExamineCopyMpjMapper smsCommonExamineCopyMpjMapper;
    @Autowired
    private NewTipsUtil newTipsUtil;

    @Override
    @Transactional
    public ResponseResult addCommonExamine(SmsCommonExamineReq smsCommonExamineReq, String user_id) {
        if (isNullOrEmpty(smsCommonExamineReq.getExamineTitle()) || isNullOrEmpty(smsCommonExamineReq.getExamineDetail())
                || isNullOrEmpty(smsCommonExamineReq.getExamineUserList()) || smsCommonExamineReq.getExamineUserList().size() < 1) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        //上传图片、附件数量校验
        String uploadPic = smsCommonExamineReq.getExaminePic();
        String uploadFile = smsCommonExamineReq.getExamineFile();
        if (!isNullOrEmpty(uploadPic)) {
            List<Object> picList = JSONObject.parseArray(uploadPic, Object.class);
            if (picList != null && picList.size() > UPLOAD_PIC_MAX_NUM) {
                return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_PIC_OVER_MAX_NUM);
            }
        }
        if (!isNullOrEmpty(uploadFile)) {
            List<Object> fileList = JSONObject.parseArray(uploadFile, Object.class);
            if (fileList != null && fileList.size() > UPLOAD_FILE_MAX_NUM) {
                return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_FILE_OVER_MAX_NUM);
            }
        }

        SmsCommonExamine addCommonExamine = new SmsCommonExamine();
        BeanUtils.copyProperties(smsCommonExamineReq, addCommonExamine);
        addCommonExamine.setExamineApplyUser(user_id);
        addCommonExamine.setExamineStatus(EXAMINE_STATUS_WAIT_ALLOW);
        smsCommonExamineMapper.insert(addCommonExamine);

        if (isNullOrEmpty(addCommonExamine.getId())) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.ADD_FAIL));
        }

        //流程去重判断
        List<String> examineDistinctList = smsCommonExamineReq.getExamineUserList().stream().distinct().collect(Collectors.toList());
        if (examineDistinctList.size() != smsCommonExamineReq.getExamineUserList().size()) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_USER_REPEAT));
        }

        int sort = 1;
        boolean first_flag = true;
        String process_detail_id = "";
        for (String examine_user_id : smsCommonExamineReq.getExamineUserList()) {
            SmsUser smsUser = smsUserMapper.selectById(examine_user_id);
            if (smsUser == null || isNullOrEmpty(smsUser.getId())) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.USER_NOT_EXIST));
            }
            SmsCommonExamineProcess addCommonExamineProcess = new SmsCommonExamineProcess();
            addCommonExamineProcess.setProcessUserId(examine_user_id);
            addCommonExamineProcess.setProcessStatus(EXAMINE_STATUS_WAIT_ALLOW);
            addCommonExamineProcess.setExamineId(addCommonExamine.getId());
            addCommonExamineProcess.setProcessSort(sort++);
            smsCommonExamineProcessMapper.insert(addCommonExamineProcess);

            if (first_flag) {
                first_flag = false;
                process_detail_id = addCommonExamineProcess.getId();
            }

        }

        if (smsCommonExamineReq.getCopyUserList() != null && smsCommonExamineReq.getCopyUserList().size() > 0) {
            List<String> distinctList = smsCommonExamineReq.getCopyUserList().stream().distinct().collect(Collectors.toList());
            for (String copy_user_id : distinctList) {
                SmsUser smsUser = smsUserMapper.selectById(copy_user_id);
                if (smsUser == null || isNullOrEmpty(smsUser.getId())) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.USER_NOT_EXIST));
                }
                SmsCommonExamineCopy addCommonExamineCopy = new SmsCommonExamineCopy();
                addCommonExamineCopy.setCopyUserId(copy_user_id);
                addCommonExamineCopy.setExamineId(addCommonExamine.getId());
                smsCommonExamineCopyMapper.insert(addCommonExamineCopy);
            }
        }

        //消息通知
        List<String> range_id_list = new ArrayList<>();
        range_id_list.add(smsCommonExamineReq.getExamineUserList().get(0));
        newTipsUtil.addNewTips(TipsTypeEnum.TIPS_TYPE_ENUM_ALLOW,
                user_id,
                RangeTypeEnum.RANGE_TYPE_ENUM_PERSON,
                range_id_list,
                CopyTypeEnum.COPY_TYPE_ENUM_PERSON,
                smsCommonExamineReq.getCopyUserList(),
                AppTypeEnum.APP_TYPE_ENUM_COMMON_EXAMINE,
                addCommonExamine.getId(),
                null,
                process_detail_id
        );
        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult cancelCommonExamine(SmsCommonExamineReq smsCommonExamineReq, String user_id) {
        String examine_id = smsCommonExamineReq.getExamineId();
        if (isNullOrEmpty(examine_id)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        SmsCommonExamine smsCommonExamine = smsCommonExamineMapper.selectOne(new QueryWrapper<SmsCommonExamine>()
                .lambda()
                .eq(SmsCommonExamine::getId, examine_id)
                .eq(SmsCommonExamine::getExamineApplyUser, user_id));
        if (smsCommonExamine == null || isNullOrEmpty(smsCommonExamine.getId())) {
            return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_NOT_EXIST);
        }

        List<SmsCommonExamineProcess> processList = smsCommonExamineProcessMapper.selectList(new QueryWrapper<SmsCommonExamineProcess>()
                .lambda()
                .eq(SmsCommonExamineProcess::getExamineId, examine_id)
                .ne(SmsCommonExamineProcess::getProcessStatus, EXAMINE_STATUS_WAIT_ALLOW));
        if (processList != null && processList.size() > 0) {
            return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_CANCEL_FAIL);
        }

        SmsCommonExamine updateCommonExamine = new SmsCommonExamine();
        updateCommonExamine.setId(examine_id);
        updateCommonExamine.setExamineStatus(EXAMINE_STATUS_CANCEL);
        updateCommonExamine.setEndTime(new Date());
        smsCommonExamineMapper.updateById(updateCommonExamine);

        smsCommonExamineProcessMapper.delete(new QueryWrapper<SmsCommonExamineProcess>()
                .lambda()
                .eq(SmsCommonExamineProcess::getExamineId, examine_id));

        //消息通知
        newTipsUtil.cancelFinishTips(smsCommonExamineReq.getExamineId());

        return CommonResult.success();
    }

    @Override
    public ResponseResult getCommonExamineList(String search_str, String user_id, Integer examine_type,
                                               Integer pageNum, Integer pageSize) {
        if (isNullOrEmpty(examine_type)) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        List<SmsCommonExamineResp> respList = new ArrayList<>();
        int total = 0;
        if (examine_type == EXAMINE_TYPE_APPLY) {
            Page<SmsCommonExamine> page = new Page<>(pageNum, pageSize);
            QueryWrapper<SmsCommonExamine> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(SmsCommonExamine::getExamineApplyUser, user_id)
                    .orderByDesc(SmsCommonExamine::getCreateTime);
            if (!isNullOrEmpty(search_str)) {
                queryWrapper.lambda().like(SmsCommonExamine::getExamineTitle, search_str);
            }
            smsCommonExamineMapper.selectPage(page, queryWrapper);
            respList = page.getRecords()
                    .stream()
                    .map(smsCommonExamine -> {
                        SmsCommonExamineResp smsCommonExamineResp = new SmsCommonExamineResp();
                        BeanUtils.copyProperties(smsCommonExamine, smsCommonExamineResp);
                        smsCommonExamineResp.setExamineCreateTime(smsCommonExamine.getCreateTime());
                        smsCommonExamineResp.setExamineId(smsCommonExamine.getId());

                        SmsUser smsUser = cacheUtil.getUserInfo(smsCommonExamine.getExamineApplyUser());
                        SmsExamineUserResp smsExamineUserResp = new SmsExamineUserResp();
                        if (smsUser != null) {
                            BeanUtils.copyProperties(smsUser, smsExamineUserResp);
                        }
                        smsCommonExamineResp.setExamineApplyUserInfo(smsExamineUserResp);

                        return smsCommonExamineResp;
                    })
                    .collect(Collectors.toList());
            total = (int) page.getTotal();
        } else if (examine_type == EXAMINE_TYPE_COPY_ME) {
            Page<SmsCommonExamineMPJResp> page = new Page<>(pageNum, pageSize);
            MPJLambdaWrapper<SmsCommonExamineCopy> mpjLambdaWrapper = new MPJLambdaWrapper<>();
            mpjLambdaWrapper.selectAll(SmsCommonExamineCopy.class)
                    .selectAll(SmsCommonExamine.class)
                    .selectAs(SmsCommonExamine::getCreateTime, "examineCreateTime")
                    .leftJoin(SmsCommonExamine.class, SmsCommonExamine::getId, SmsCommonExamineCopy::getExamineId)
                    .eq(SmsCommonExamineCopy::getCopyUserId, user_id)
                    .orderByDesc(SmsCommonExamine::getCreateTime);

            if (!isNullOrEmpty(search_str)) {
                mpjLambdaWrapper.like(SmsCommonExamine::getExamineTitle, search_str);
            }
            smsCommonExamineCopyMpjMapper.selectJoinPage(page, SmsCommonExamineMPJResp.class, mpjLambdaWrapper);

            respList = page.getRecords()
                    .stream()
                    .map(smsCommonExamine -> {
                        SmsCommonExamineResp smsCommonExamineResp = new SmsCommonExamineResp();
                        BeanUtils.copyProperties(smsCommonExamine, smsCommonExamineResp);

                        SmsUser smsUser = cacheUtil.getUserInfo(smsCommonExamine.getExamineApplyUser());
                        SmsExamineUserResp smsExamineUserResp = new SmsExamineUserResp();
                        if (smsUser != null) {
                            BeanUtils.copyProperties(smsUser, smsExamineUserResp);
                        }
                        smsCommonExamineResp.setExamineApplyUserInfo(smsExamineUserResp);

                        SmsUser copyUser = cacheUtil.getUserInfo(smsCommonExamine.getCopyUserId());
                        SmsExamineUserResp smsExamineCopyUserResp = new SmsExamineUserResp();
                        if (smsUser != null) {
                            BeanUtils.copyProperties(copyUser, smsExamineCopyUserResp);
                        }
                        smsCommonExamineResp.setExamineCopyUserInfo(smsExamineCopyUserResp);

                        return smsCommonExamineResp;
                    })
                    .collect(Collectors.toList());
            total = (int) page.getTotal();
        } else if (examine_type == EXAMINE_TYPE_ALLOWED) {
            Page<SmsCommonExamineMPJResp> page = new Page<>(pageNum, pageSize);
            MPJLambdaWrapper<SmsCommonExamineProcess> mpjLambdaWrapper = new MPJLambdaWrapper<>();
            mpjLambdaWrapper.selectAll(SmsCommonExamineProcess.class)
                    .selectAll(SmsCommonExamine.class)
                    .selectAs(SmsCommonExamine::getCreateTime, "examineCreateTime")
                    .leftJoin(SmsCommonExamine.class, SmsCommonExamine::getId, SmsCommonExamineProcess::getExamineId)
                    .eq(SmsCommonExamineProcess::getProcessUserId, user_id)
//                    .orderByDesc(SmsCommonExamine::getCreateTime)
                    .orderByDesc(SmsCommonExamineProcess::getProcessTime)
            ;
            if (!isNullOrEmpty(search_str)) {
                mpjLambdaWrapper.like(SmsCommonExamine::getExamineTitle, search_str);
            }

            mpjLambdaWrapper.and(wrapper -> {
                wrapper.eq(SmsCommonExamineProcess::getProcessStatus, EXAMINE_STATUS_PASS)
                        .or()
                        .eq(SmsCommonExamineProcess::getProcessStatus, EXAMINE_STATUS_DENY);
            });

            smsCommonExamineProcessMpjMapper.selectJoinPage(page, SmsCommonExamineMPJResp.class, mpjLambdaWrapper);

            respList = page.getRecords()
                    .stream()
                    .map(smsCommonExamineMPJResp -> {
                        SmsCommonExamineResp smsCommonExamineResp = new SmsCommonExamineResp();
                        BeanUtils.copyProperties(smsCommonExamineMPJResp, smsCommonExamineResp);

                        SmsUser smsUser = cacheUtil.getUserInfo(smsCommonExamineResp.getExamineApplyUser());
                        SmsExamineUserResp smsExamineUserResp = new SmsExamineUserResp();
                        if (smsUser != null) {
                            BeanUtils.copyProperties(smsUser, smsExamineUserResp);
                        }
                        smsCommonExamineResp.setExamineApplyUserInfo(smsExamineUserResp);
                        return smsCommonExamineResp;
                    })
                    .collect(Collectors.toList());
            total = (int) page.getTotal();
        } else if (examine_type == EXAMINE_TYPE_ALLOW_WAIT_ME) {
            Page<SmsCommonExamineMPJResp> page = new Page<>(pageNum, pageSize);
            MPJLambdaWrapper<SmsCommonExamineProcess> mpjLambdaWrapper = new MPJLambdaWrapper<>();
            mpjLambdaWrapper.selectAll(SmsCommonExamineProcess.class)
                    .selectAll(SmsCommonExamine.class)
                    .selectAs(SmsCommonExamineProcess::getId, "examineProcessId")
                    .selectAs(SmsCommonExamine::getCreateTime, "examineCreateTime")
                    .leftJoin(SmsCommonExamine.class, SmsCommonExamine::getId, SmsCommonExamineProcess::getExamineId)
                    .eq(SmsCommonExamineProcess::getProcessUserId, user_id)
                    .orderByDesc(SmsCommonExamine::getCreateTime)
            ;
            if (!isNullOrEmpty(search_str)) {
                mpjLambdaWrapper.like(SmsCommonExamine::getExamineTitle, search_str);
            }

            mpjLambdaWrapper.eq(SmsCommonExamineProcess::getProcessStatus, EXAMINE_STATUS_WAIT_ALLOW);
            smsCommonExamineProcessMpjMapper.selectJoinPage(page, SmsCommonExamineMPJResp.class, mpjLambdaWrapper);

            respList = page.getRecords()
                    .stream()
                    .filter(smsCommonExamineMPJResp -> {
                        if (smsCommonExamineMPJResp.getProcessSort() == 1) {
                            return true;
                        }
                        SmsCommonExamineProcess examineProcess = smsCommonExamineProcessMapper.selectOne(new QueryWrapper<SmsCommonExamineProcess>()
                                .lambda()
                                .eq(SmsCommonExamineProcess::getExamineId, smsCommonExamineMPJResp.getExamineId())
                                .eq(SmsCommonExamineProcess::getProcessSort, smsCommonExamineMPJResp.getProcessSort() - 1));
                        if (examineProcess.getProcessStatus() == EXAMINE_STATUS_WAIT_ALLOW) {
                            return false;
                        }
                        return true;
                    })
                    .map(smsCommonExamineMPJResp -> {
                        SmsCommonExamineResp smsCommonExamineResp = new SmsCommonExamineResp();
                        BeanUtils.copyProperties(smsCommonExamineMPJResp, smsCommonExamineResp);

                        SmsUser smsUser = cacheUtil.getUserInfo(smsCommonExamineResp.getExamineApplyUser());
                        SmsExamineUserResp smsExamineUserResp = new SmsExamineUserResp();
                        if (smsUser != null) {
                            BeanUtils.copyProperties(smsUser, smsExamineUserResp);
                        }
                        smsCommonExamineResp.setExamineApplyUserInfo(smsExamineUserResp);
                        return smsCommonExamineResp;
                    })
                    .collect(Collectors.toList());
            total = respList.size();
        }
        return CommonResult.success(respList, total);
    }

    @Override
    public ResponseResult getCommonExamineDetail(String id, Integer examine_type, String user_id) {
        SmsCommonExamine smsCommonExamine = smsCommonExamineMapper.selectById(id);
        if (smsCommonExamine == null || isNullOrEmpty(smsCommonExamine.getId())) {
            return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_NOT_EXIST);
        }

//        switch (examine_type) {
//            case EXAMINE_TYPE_ALLOW_WAIT_ME:
//                List<SmsCommonExamineProcess> waitMeProcessList = smsCommonExamineProcessMapper.selectList(new QueryWrapper<SmsCommonExamineProcess>()
//                        .lambda()
//                        .eq(SmsCommonExamineProcess::getProcessUserId, user_id)
//                        .eq(SmsCommonExamineProcess::getProcessStatus, EXAMINE_STATUS_WAIT_ALLOW)
//                        .eq(SmsCommonExamineProcess::getExamineId, id));
//                if (waitMeProcessList == null || waitMeProcessList.size() < 1) {
//                    return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_NOT_EXIST);
//                }
//                break;
//            case EXAMINE_TYPE_ALLOWED:
//                List<SmsCommonExamineProcess> allowProcessList = smsCommonExamineProcessMapper.selectList(new QueryWrapper<SmsCommonExamineProcess>()
//                        .lambda()
//                        .eq(SmsCommonExamineProcess::getProcessUserId, user_id)
//                        .eq(SmsCommonExamineProcess::getExamineId, id)
//                        .and(wrapper -> {
//                            wrapper.eq(SmsCommonExamineProcess::getProcessStatus, EXAMINE_STATUS_PASS)
//                                    .or()
//                                    .eq(SmsCommonExamineProcess::getProcessStatus, EXAMINE_STATUS_DENY);
//                        }));
//                if (allowProcessList == null || allowProcessList.size() < 1) {
//                    return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_NOT_EXIST);
//                }
//                break;
//            case EXAMINE_TYPE_COPY_ME:
//                List<SmsCommonExamineCopy> copyMeList = smsCommonExamineCopyMapper.selectList(new QueryWrapper<SmsCommonExamineCopy>()
//                        .lambda()
//                        .eq(SmsCommonExamineCopy::getCopyUserId, user_id)
//                        .eq(SmsCommonExamineCopy::getExamineId, id));
//                if (copyMeList == null || copyMeList.size() < 1) {
//                    return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_NOT_EXIST);
//                }
//                break;
//            case EXAMINE_TYPE_APPLY:
//                if (!smsCommonExamine.getExamineApplyUser().equals(user_id)) {
//                    return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_NOT_EXIST);
//                }
//                break;
//            default:
//                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
//        }

        SmsCommonExamineDetailResp smsCommonExamineDetailResp = new SmsCommonExamineDetailResp();
        BeanUtils.copyProperties(smsCommonExamine, smsCommonExamineDetailResp);

        SmsUser smsUser1 = cacheUtil.getUserInfo(smsCommonExamine.getExamineApplyUser());
        SmsExamineUserResp smsExamineUserResp1 = new SmsExamineUserResp();
        if (smsUser1 != null) {
            BeanUtils.copyProperties(smsUser1, smsExamineUserResp1);
        }
        smsCommonExamineDetailResp.setExamineApplyUserInfo(smsExamineUserResp1);

        //获取流程集合
        List<SmsCommonExamineProcessResp> processRespList = smsCommonExamineProcessMapper.selectList(new QueryWrapper<SmsCommonExamineProcess>()
                .lambda()
                .eq(SmsCommonExamineProcess::getExamineId, id)
                .orderByAsc(SmsCommonExamineProcess::getProcessSort))
                .stream()
                .map(process -> {
                            SmsCommonExamineProcessResp smsCommonExamineProcessResp =
                                    new SmsCommonExamineProcessResp();
                            BeanUtils.copyProperties(process, smsCommonExamineProcessResp);

                            SmsUser smsUser = cacheUtil.getUserInfo(process.getProcessUserId());
                            SmsExamineUserResp smsExamineUserResp = new SmsExamineUserResp();
                            if (smsUser != null) {
                                BeanUtils.copyProperties(smsUser, smsExamineUserResp);
                            }
                            smsCommonExamineProcessResp.setExamineProcessUserInfo(smsExamineUserResp);
                            return smsCommonExamineProcessResp;
                        }
                )
                .collect(Collectors.toList());
        smsCommonExamineDetailResp.setProcessRespList(processRespList);

        //获取抄送集合

        List<SmsCommonExamineCopyResp> copyRespList = smsCommonExamineCopyMapper.selectList(new QueryWrapper<SmsCommonExamineCopy>()
                .lambda()
                .eq(SmsCommonExamineCopy::getExamineId, id))
                .stream()
                .map(copy -> {
                    SmsCommonExamineCopyResp smsCommonExamineCopyResp =
                            new SmsCommonExamineCopyResp();
                    BeanUtils.copyProperties(copy, smsCommonExamineCopyResp);

                    SmsUser smsUser = cacheUtil.getUserInfo(copy.getCopyUserId());
                    SmsExamineUserResp smsExamineUserResp = new SmsExamineUserResp();
                    if (smsUser != null) {
                        BeanUtils.copyProperties(smsUser, smsExamineUserResp);
                    }
                    smsCommonExamineCopyResp.setExamineCopyUserInfo(smsExamineUserResp);

                    return smsCommonExamineCopyResp;
                })
                .collect(Collectors.toList());
        smsCommonExamineDetailResp.setCopyRespList(copyRespList);
        return CommonResult.success(smsCommonExamineDetailResp);
    }

    @Override
    @Transactional
    public ResponseResult allowCommonExamine(SmsCommonExamineReq smsCommonExamineReq, String user_id) {
        if (isNullOrEmpty(smsCommonExamineReq.getExamineId()) || isNullOrEmpty(smsCommonExamineReq.getExamineProcessId())
                || isNullOrEmpty(smsCommonExamineReq.getExamineStatus())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        if (smsCommonExamineReq.getExamineStatus() != EXAMINE_STATUS_PASS && smsCommonExamineReq.getExamineStatus() != EXAMINE_STATUS_DENY) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsCommonExamine smsCommonExamine = smsCommonExamineMapper.selectById(smsCommonExamineReq.getExamineId());
        if (smsCommonExamine == null || isNullOrEmpty(smsCommonExamine.getId())) {
            return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_NOT_EXIST);
        }

        SmsCommonExamineProcess examineProcess = smsCommonExamineProcessMapper.selectOne(new QueryWrapper<SmsCommonExamineProcess>()
                .lambda()
                .eq(SmsCommonExamineProcess::getExamineId, smsCommonExamineReq.getExamineId())
                .eq(SmsCommonExamineProcess::getProcessUserId, user_id)
                .eq(SmsCommonExamineProcess::getProcessStatus, EXAMINE_STATUS_WAIT_ALLOW));

        if (examineProcess == null || isNullOrEmpty(examineProcess.getExamineId())) {
            return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_PROCESS_ALLOW_FAIL);
        }

        List<SmsCommonExamineProcess> processList = smsCommonExamineProcessMapper.selectList(new QueryWrapper<SmsCommonExamineProcess>()
                .lambda()
                .eq(SmsCommonExamineProcess::getExamineId, smsCommonExamineReq.getExamineId()));

        if (examineProcess.getProcessSort() != 1) {
            int index = examineProcess.getProcessSort() - 2;
            SmsCommonExamineProcess smsCommonExamineProcess = processList.get(index);
            if (smsCommonExamineProcess.getProcessStatus() == EXAMINE_STATUS_WAIT_ALLOW) {
                return CommonResult.failed(CommonCodeEnum.COMMON_EXAMINE_PROCESS_PREVIOUS_NOT_FINISH);
            }
        }

        //修改节点流程
        Date nowDate = new Date();
        SmsCommonExamineProcess updateExamineProcess = new SmsCommonExamineProcess();
        updateExamineProcess.setId(examineProcess.getId());
        updateExamineProcess.setProcessStatus(smsCommonExamineReq.getExamineStatus());
        if (!isNullOrEmpty(smsCommonExamineReq.getExamineRemark())) {
            updateExamineProcess.setProcessRemark(smsCommonExamineReq.getExamineRemark());
        }
        updateExamineProcess.setProcessTime(nowDate);
        smsCommonExamineProcessMapper.updateById(updateExamineProcess);

        boolean is_done = false;

        //判断是否最后流程或是否拒绝
        if (examineProcess.getProcessSort() == processList.size()
                || smsCommonExamineReq.getExamineStatus() == EXAMINE_STATUS_DENY) {
            is_done = true;

            SmsCommonExamine updateExamine = new SmsCommonExamine();
            updateExamine.setId(smsCommonExamineReq.getExamineId());
            updateExamine.setExamineStatus(smsCommonExamineReq.getExamineStatus());
            updateExamine.setEndTime(nowDate);
            smsCommonExamineMapper.updateById(updateExamine);
        }

        //消息通知
        boolean result = false;
        if (smsCommonExamineReq.getExamineStatus() == 1) {
            result = true;
        }

        if (is_done) {
            newTipsUtil.allowFinishTips(smsCommonExamineReq.getExamineId(), user_id, result);
        } else {
            //获取下一个审批人id
            List<String> range_id_list = new ArrayList<>();
            range_id_list.add(processList.get(examineProcess.getProcessSort()).getProcessUserId());

            newTipsUtil.allowContinueTips(smsCommonExamineReq.getExamineId(),
                    user_id,
                    RangeTypeEnum.RANGE_TYPE_ENUM_PERSON,
                    range_id_list,
                    processList.get(examineProcess.getProcessSort()).getId());
        }
        return CommonResult.success();
    }


    @Autowired
    private PictureUtil pictureUtil;

    @Override
    @Async
    public Future<ResponseResult> tableDownload(String apply_id, HttpServletResponse response) {
        SmsCommonExamine smsCommonExamine = smsCommonExamineMapper.selectById(apply_id);
        if (smsCommonExamine == null || smsCommonExamine.getId() == null) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.PAYMENT_NOT_EXIST));
        }
//        if (smsCommonExamine.getExamineStatus() == EXAMINE_STATUS_WAIT_ALLOW) {
//            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.WORK_APPLICATION_DOWNLOAD_FAIL));
//        }

        String OSName = System.getProperty("os.name");
        String filePath = OSName.toLowerCase().startsWith("win") ? fileSavePathConstant.getFILE_DOWNLOAD_PATH()
                : fileSavePathConstant.getFILE_DOWNLOAD_PATH_LINUX();

        String newFilePath = filePath + apply_id + ".docx";
        String pdfFilePath = filePath + apply_id + ".pdf";

        File pdfFile = new File(pdfFilePath);

//        if (!pdfFile.exists()) {
            try {
                Map<String, Object> map = new HashMap<>();
                map.put("examineTitle", filterResultNull(smsCommonExamine.getExamineTitle()));

                SmsUser user = smsUserMapper.selectById(smsCommonExamine.getExamineApplyUser());
                if (user != null) {
                    map.put("applyUser", user.getRealName());
                }

                map.put("applyDetail", filterResultNull(smsCommonExamine.getExamineDetail()));

                //封装图片
                List<Map<String, Object>> picList = new ArrayList<>();
                if (!isNullOrEmpty(smsCommonExamine.getExaminePic())) {
                    List<SmsCommonExaminePicEntity> examinePicEntityList = JSONObject.parseArray(
                            smsCommonExamine.getExaminePic(), SmsCommonExaminePicEntity.class);
                    if (examinePicEntityList != null && examinePicEntityList.size() > 0) {
                        for (SmsCommonExaminePicEntity picEntity : examinePicEntityList) {
                            String[] splitStr = picEntity.getUrl().split("=");
                            String fileName = splitStr[splitStr.length - 1];

                            String[] splitType = fileName.split("u002E");
                            String type = splitType[splitType.length - 1];
                            PictureType pictureType = pictureUtil.getPictureType(type);

                            File picture = new File(filePath + fileName);
                            BufferedImage sourceImg = ImageIO.read(picture);
                            Integer width = sourceImg.getWidth();
                            Integer height = sourceImg.getHeight();
                            if((width*1.0)/IMG_MAX_WIDTH < (height*1.0)/IMG_MAX_HEIGHT){
                                if(width > IMG_MAX_WIDTH){
                                    height = Integer.parseInt(new java.text.DecimalFormat("0").format(height * IMG_MAX_WIDTH/(width*1.0)));
                                }
                                if(height > IMG_MAX_HEIGHT){
                                    width = Integer.parseInt(new java.text.DecimalFormat("0").format(width * IMG_MAX_HEIGHT/(height*1.0)));
                                }
                            } else {
                                if(height > IMG_MAX_HEIGHT){
                                    width = Integer.parseInt(new java.text.DecimalFormat("0").format(width * IMG_MAX_HEIGHT/(height*1.0)));
                                }
                                if(width > IMG_MAX_WIDTH){
                                    height = Integer.parseInt(new java.text.DecimalFormat("0").format(height * IMG_MAX_WIDTH/(width*1.0)));
                                }
                            }

                            File file = new File(filePath + fileName);
                            if (file.exists()){
                                InputStream inputStream = new FileInputStream(file);
                                PictureRenderData pictures = Pictures.ofStream(inputStream,
                                        pictureType).size(width,height)
                                        .create();

                                Map<String, Object> picMap = new HashMap<>();
                                picMap.put("examinePic", pictures);
                                picList.add(picMap);
                            }
                        }
                    }
                    if (picList.size() > 0) {
                        map.put("examinePicList", picList);
                    }
                }

                //封装文件
                List<Map<String, Object>> fileList = new ArrayList<>();
                if (!isNullOrEmpty(smsCommonExamine.getExamineFile())) {
                    List<SmsCommonExamineFileEntity> examineFileEntityList = JSONObject.parseArray(
                            smsCommonExamine.getExamineFile(), SmsCommonExamineFileEntity.class);
                    if (examineFileEntityList != null && examineFileEntityList.size() > 0) {
                        for (SmsCommonExamineFileEntity fileEntity : examineFileEntityList) {
                            String[] splitStr = fileEntity.getUrl().split("=");
                            String fileName = splitStr[splitStr.length - 1];

                            Map<String, Object> picMap = new HashMap<>();
                            picMap.put("examineFile", fileName);
                            fileList.add(picMap);
                        }
                    }
                    if (fileList.size() > 0) {
                        map.put("examineFileList", fileList);
                    }
                }

                //获取申请流程
                List<SmsCommonExamineProcess> detailList = smsCommonExamineProcessMapper.selectList(new QueryWrapper<SmsCommonExamineProcess>()
                        .lambda()
                        .eq(SmsCommonExamineProcess::getExamineId, apply_id));
                if (detailList != null && detailList.size() > 0) {
                    List<SmsCommonExamineProcessTableEntity> tableEntityList = new ArrayList<>();
                    for (SmsCommonExamineProcess detail : detailList) {
                        if (detail.getProcessStatus() == EXAMINE_STATUS_PASS || detail.getProcessStatus() == EXAMINE_STATUS_DENY) {
                            SmsCommonExamineProcessTableEntity processTableEntity =
                                    new SmsCommonExamineProcessTableEntity();

                            SmsUser smsUser = smsUserMapper.selectById(detail.getProcessUserId());
                            if (smsUser != null) {
                                processTableEntity.setExamineUser(smsUser.getRealName());
                            }

                            if (detail.getProcessStatus() == EXAMINE_STATUS_PASS) {
                                processTableEntity.setAllowStatus("同意");
                            } else {
                                processTableEntity.setAllowStatus("拒绝");
                            }

                            processTableEntity.setAllowOption(filterResultNull(detail.getProcessRemark()));
                            if (detail.getProcessTime() != null) {
                                processTableEntity.setAllowTime(TimeUtil.DateHanZiSimpleFormat(detail.getProcessTime()));
                            }
                            tableEntityList.add(processTableEntity);
                        }
                    }
                    if (tableEntityList.size() > 0) {
                        map.put("lists", tableEntityList);
                    }
                }

                ClassPathResource resource = new ClassPathResource("applyTemplates/commonExamineTemplate.docx");
                InputStream is = resource.getInputStream();
                FileOutputStream outputStream = new FileOutputStream(newFilePath);

                XWPFTemplate template = XWPFTemplate.compile(is);

                //配置循环表格
                Configure config = template.getConfig();
                config.customPolicy("lists", new LoopRowTableRenderPolicy());

                template.render(map);
                template.write(outputStream);

                is.close();
                outputStream.close();
                template.close();

                //word转pdf
                File destOri = new File(newFilePath);
                FileInputStream fileInputStream = new FileInputStream(destOri);
                FileOutputStream fileOutputStream = new FileOutputStream(pdfFilePath);

                Document document = new Document();
                document.loadFromStream(fileInputStream, FileFormat.Docx);
                //保存为PDF
                document.saveToFile(pdfFilePath, FileFormat.PDF);

                fileInputStream.close();
                fileOutputStream.close();
                document.close();

                log.debug("文件生成完成!");
            } catch (Exception e) {
                e.printStackTrace();
                return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
            }
//        }
        try {
            // 加载PDF文档
            PDDocument doc = PDDocument.load(pdfFile);
            doc.setAllSecurityToBeRemoved(true);
            // 创建水印
            String watermark = "南充电影工业职业学院";
            PDPageContentStream contentStream;

            for (PDPage page : doc.getPages()) {
                contentStream = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);

                //加载字体
                ClassPathResource resource = new ClassPathResource("fonts/123.ttf");
                InputStream is = resource.getInputStream();
                PDFont font = PDType0Font.load(doc, is);


                int startX = 0; // 起始位置 x 坐标
                int startY = 0; // 起始位置 y 坐标
                float angle = -45; // 角度
                float interval = 220; // 间隔
                float opacity = 0.3f; // 透明度
                int colorR = 127; // 颜色 red 值
                int colorG = 127; // 颜色 green 值
                int colorB = 127; // 颜色 blue 值

                //透明的
                PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
                r0.setNonStrokingAlphaConstant(opacity);
                r0.setAlphaSourceFlag(true);
                contentStream.setGraphicsStateParameters(r0);

                //水印颜色
                contentStream.setNonStrokingColor(colorR, colorG, colorB);
                contentStream.beginText();
                contentStream.setFont(font, 30f);

                int x_times = (int) Math.ceil(page.getMediaBox().getWidth() / interval);
                int y_times = (int) Math.ceil(page.getMediaBox().getHeight() / interval);
                for (int x = startX; x <= x_times; x++) {
                    for (int y = startY; y <= y_times; y++) {
                        contentStream.setTextRotation(angle, (x * interval), (y * interval));
                        contentStream.showText(watermark);
                    }
                }
                contentStream.endText();
                contentStream.restoreGraphicsState();
                contentStream.close();
                is.close();
            }

//            response.reset();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/vnd.pdf;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("通用审批预览.pdf", "utf-8"));
            response.setHeader("file-type", "download");
            response.setHeader("file-name", URLEncoder.encode("通用审批预览.pdf", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
            //刷新缓冲
            response.flushBuffer();

            // 保存PDF文档
            doc.save(response.getOutputStream());
            doc.close();
        } catch (Exception e) {
            e.printStackTrace();
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));

        }
        return null;
    }

    private String filterResultNull(String resultStr) {
        if (resultStr == null || resultStr.equals("null")) {
            return "";
        }
        return resultStr;
    }

    @Override
    public ResponseResult getExamineHistoryList(String apply_user,
                                                String examine_id,
                                                String examine_title,
                                                String examine_status,
                                                Integer pageNum,
                                                Integer pageSize) {
        QueryWrapper<SmsCommonExamine> queryWrapper = new QueryWrapper<>();
        if (!isNullOrEmpty(examine_id)) {
            queryWrapper.lambda().eq(SmsCommonExamine::getId, examine_id);
        }
        if (!isNullOrEmpty(examine_title)) {
            queryWrapper.lambda().like(SmsCommonExamine::getExamineTitle, examine_title);
        }
        if (!isNullOrEmpty(examine_status)) {
            queryWrapper.lambda().eq(SmsCommonExamine::getExamineStatus, examine_status);
        }

        if (!isNullOrEmpty(apply_user)) {
            List<String> userList = smsUserMapper.selectList(new QueryWrapper<SmsUser>()
                    .lambda()
                    .like(SmsUser::getRealName, apply_user))
                    .stream()
                    .map(SmsUser::getId)
                    .collect(Collectors.toList());
            if (userList.size() > 0) {
                queryWrapper.lambda().in(SmsCommonExamine::getExamineApplyUser, userList);
            }
        }
        queryWrapper.lambda().orderByDesc(SmsCommonExamine::getCreateTime);
        Page<SmsCommonExamine> page = new Page<>(pageNum, pageSize);
        smsCommonExamineMapper.selectPage(page, queryWrapper);

        List<SmsCommonExamineResp> list = page.getRecords()
                .stream()
                .map(common -> {
                    SmsCommonExamineResp commonExamineResp = new SmsCommonExamineResp();
                    BeanUtils.copyProperties(common, commonExamineResp);
                    commonExamineResp.setExamineId(common.getId());

                    SmsUser smsUser = cacheUtil.getUserInfo(commonExamineResp.getExamineApplyUser());
                    if (smsUser != null) {
                        SmsExamineUserResp user = new SmsExamineUserResp();
                        BeanUtils.copyProperties(smsUser, user);
                        commonExamineResp.setExamineApplyUserInfo(user);
                    }
                    return commonExamineResp;
                })
                .collect(Collectors.toList());
        int total = (int) page.getTotal();
        return CommonResult.success(list, total);
    }

    @Autowired
    private ApiModelUtil apiModelUtil;

    @Override
    @Async
    public Future<ResponseResult> exportExamineHistoryList(SmsCommonExamineHistoryReq req, HttpServletResponse response) {
        if (isNullOrEmpty(req.getIsExportProcess())) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        try {
            QueryWrapper<SmsCommonExamine> queryWrapper = new QueryWrapper<>();
            if (!isNullOrEmpty(req.getExamineId())) {
                queryWrapper.lambda().eq(SmsCommonExamine::getId, req.getExamineId());
            }
            if (!isNullOrEmpty(req.getExamineTitle())) {
                queryWrapper.lambda().like(SmsCommonExamine::getExamineTitle, req.getExamineTitle());
            }
            if (!isNullOrEmpty(req.getExamineStatus())) {
                queryWrapper.lambda().eq(SmsCommonExamine::getExamineStatus, req.getExamineStatus());
            }
            if (!isNullOrEmpty(req.getApplyUser())) {
                List<String> userList = smsUserMapper.selectList(new QueryWrapper<SmsUser>()
                        .lambda()
                        .like(SmsUser::getRealName, req.getApplyUser()))
                        .stream()
                        .map(SmsUser::getId)
                        .collect(Collectors.toList());
                if (userList.size() > 0) {
                    queryWrapper.lambda().in(SmsCommonExamine::getExamineApplyUser, userList);
                }
            }
            queryWrapper.lambda().orderByDesc(SmsCommonExamine::getCreateTime);
            List<SmsCommonExamine> list = smsCommonExamineMapper.selectList(queryWrapper);
            //表头数据
            String[] header = req.getLimitColumn().toArray(new String[0]);
            double sheetNum;
            //声明一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook();
            if (list != null && list.size() > 0) {
                sheetNum = Math.ceil((double) list.size() / PER_SHEET_NUM);
                for (int k = 0; k < sheetNum; k++) {
                    //生成一个表格，设置表格名称为"资源导出表"
                    HSSFSheet sheet = workbook.createSheet("通用审批记录导出表" + (k + 1));

                    //设置表格列宽度为10个字节
                    sheet.setDefaultColumnWidth(12);
                    //创建标题的显示样式
                    HSSFCellStyle headerStyle = workbook.createCellStyle();
                    headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
                    headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

                    HSSFFont f = workbook.createFont();
                    f.setFontHeightInPoints((short) 10);//字号
                    f.setBold(true);//加粗
                    headerStyle.setFont(f);
                    //创建第一行表头
                    HSSFRow headrow = sheet.createRow(0);

                    //遍历添加表头
                    for (int i = 0; i < header.length + 1; i++) {
                        //创建一个单元格
                        HSSFCell cell = headrow.createCell(i);

                        if (i == 0) {
                            //创建一个内容对象
                            HSSFRichTextString text = new HSSFRichTextString("序号");
                            //将内容对象的文字内容写入到单元格中
                            cell.setCellValue(text);
                            cell.setCellStyle(headerStyle);
                            continue;
                        }
                        //创建一个内容对象
                        String header1 = apiModelUtil.getFieldValueByFieldName(SmsCommonExamine.class, header[i - 1]);
                        HSSFRichTextString text = new HSSFRichTextString(header1);

                        //将内容对象的文字内容写入到单元格中
                        cell.setCellValue(text);
                        cell.setCellStyle(headerStyle);
                    }

                    //判断是否需要添加流程表头
                    if (req.getIsExportProcess() == EXPORT_PROCESS_TRUE) {
                        HSSFCell cell = headrow.createCell(header.length + 1);

                        HSSFRichTextString text = new HSSFRichTextString("审批流程");

                        //将内容对象的文字内容写入到单元格中
                        cell.setCellValue(text);
                        cell.setCellStyle(headerStyle);
                    }

                    int range = PER_SHEET_NUM;
                    if (k + 1 == sheetNum) {
                        range = list.size() - (PER_SHEET_NUM) * k;
                    }
                    for (int i = 0; i < range; i++) {
                        //创建一行
                        HSSFRow row1 = sheet.createRow(i + 1);
                        SmsCommonExamine commonExamine = list.get((PER_SHEET_NUM) * k + i);
                        Map map = JSONObject.parseObject(JSON.toJSONString(commonExamine), Map.class);
                        row1.createCell(0).setCellValue(new HSSFRichTextString(i + 1 + ""));
                        for (int j = 0; j < header.length; j++) {
                            String rowContent = "";
                            if (map.get(header[j]) instanceof Long) {
                                rowContent = TimeUtil.DateHanZiSimpleTimestamp((long) map.get(header[j]));
                            } else {
                                if (header[j].equals("examineApplyUser")) {
                                    SmsUser smsUser = cacheUtil.getUserInfo(commonExamine.getExamineApplyUser());
                                    if (smsUser != null) {
                                        rowContent = smsUser.getRealName();
                                    } else {
                                        rowContent = "";
                                    }
                                } else {
                                    rowContent = (String) map.get(header[j]);
                                }
                            }
                            row1.createCell(j + 1).setCellValue(new HSSFRichTextString(rowContent));
                        }

                        if (req.getIsExportProcess() == EXPORT_PROCESS_TRUE) {
                            List<SmsCommonExamineProcess> processList = smsCommonExamineProcessMapper.selectList(new QueryWrapper<SmsCommonExamineProcess>()
                                    .lambda()
                                    .eq(SmsCommonExamineProcess::getExamineId, commonExamine.getId()));
                            StringBuilder stringBuilder = new StringBuilder();
                            if (processList != null && processList.size() > 0){
                                int sort = 1;
                                for (SmsCommonExamineProcess process:processList) {
                                    if (process.getProcessStatus() != EXAMINE_STATUS_PASS && process.getProcessStatus() != EXAMINE_STATUS_DENY){
                                        sort += 1;
                                        break;
                                    }
                                    stringBuilder.append("审批节点").append(sort).append(":\n");

                                    SmsUser smsUser = smsUserMapper.selectById(process.getProcessUserId());
                                    if (smsUser==null){
                                        stringBuilder.append("审批人：").append("\n");
                                    }else {
                                        stringBuilder.append("审批人：").append(smsUser.getRealName()).append("\n");
                                    }

                                    if (process.getProcessStatus() == EXAMINE_STATUS_PASS){
                                        stringBuilder.append("审批状态：同意").append("\n");
                                    }else{
                                        stringBuilder.append("审批状态：拒绝").append("\n");
                                    }

                                    if (isNullOrEmpty(process.getProcessRemark())){
                                        stringBuilder.append("审批意见：").append("\n");
                                    }else{
                                        stringBuilder.append("审批意见：").append(process.getProcessRemark()).append("\n");
                                    }

                                    if (isNullOrEmpty(process.getProcessTime())){
                                        stringBuilder.append("审批时间：").append("\n");
                                    }else{
                                        stringBuilder.append("审批时间：").append(TimeUtil.DateHanZiSimpleFormat(process.getProcessTime()))
                                                .append("\n").append("\n");
                                    }
                                    sort++;
                                }
                            }
                            row1.createCell(header.length + 1).setCellValue(new HSSFRichTextString(stringBuilder.toString()));

                        }
                    }
                }
            }

//            response.reset();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("通用审批记录导出表.xlsx", "utf-8"));
            response.setCharacterEncoding("utf-8");
            response.setHeader("file-type", "download");
            response.setHeader("file-name", URLEncoder.encode("通用审批记录导出表.xlsx", "utf-8"));
            response.setHeader("Access-Control-Expose-Headers", "file-type,file-name");
//            //刷新缓冲
            response.flushBuffer();
            //workbook将Excel写入到response的输出流中，供页面下载
            OutputStream os = response.getOutputStream();
            workbook.write(os);

            workbook.close();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.FAIL));
        }
        return null;
    }

}
